package com.focus.wecenter.dao.impl;

import com.focus.wecenter.util.PageBean;
import com.focus.wecenter.dao.BaseDao;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * 所有dao实现类都要继承该类，它定义了实体最基本的CRUD功能
 *
 * @author focus
 * @param <T> 要操作的实体泛型
 */
@SuppressWarnings("all")
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
	
	private Class<T> clazz;
	
	@Resource(name="sessionFactory")  
    public void setMySessionFactory(SessionFactory sessionFactory){    
        super.setSessionFactory(sessionFactory);    
    }

	public BaseDaoImpl() {
		ParameterizedType pt=(ParameterizedType)this.getClass().getGenericSuperclass();
		this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
	}

	@Override
	public void add(T t){
		this.getHibernateTemplate().save(t);
	}

    @Override
	public void update(T t){
		this.getHibernateTemplate().update(t);
	}

    @Override
	public T findById(Serializable id){
		return this.getHibernateTemplate().get(clazz, id);
	}

    @Override
	public List<T> findAll(){
		return (List<T>) this.getHibernateTemplate().find("from "+clazz.getSimpleName());
	}

    @Override
	public List<T> find(DetachedCriteria criteria){
		return (List<T>) this.getHibernateTemplate().findByCriteria(criteria);
	}

    @Override
	public PageBean<T> findByPage(DetachedCriteria criteria, int currentpage, int pagesize){
		PageBean<T> pageBean = new PageBean();
		pageBean.setCurrentpage(currentpage);
		pageBean.setPagesize(pagesize);
		// 查询总记录数
		criteria.setProjection(Projections.rowCount());
		List<Number> list = (List<Number>) this.getHibernateTemplate().findByCriteria(criteria);
		if (list != null && list.size() > 0) {
			pageBean.setTotalcount(list.get(0).intValue());
		}
		// 查询对象数据
		criteria.setProjection(null);
		// 在使用别名后，会造成离线查询出来的是一个Object数组，即包含父类型和子类型，需要使用这条代码让查询结果集恢复到根的状态
		criteria.setResultTransformer(Criteria.ROOT_ENTITY);
		List<T> pageList = (List<T>) this.getHibernateTemplate().findByCriteria(criteria, (currentpage - 1) * pagesize, pagesize);
		pageBean.setList(pageList);

		return pageBean;
	}

    @Override
	public void deleteById(Serializable id) {
		T t = this.getHibernateTemplate().get(clazz, id);
		if (t != null) {
			this.getHibernateTemplate().delete(t);
		}
	}
}
